package com.hedl.practice.diyJava.encryptionandsecurity.symmetric_encryption_algorithm.test;

import org.apache.commons.lang3.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class Main {
    //加密
    private static byte[] encrypt(byte[] key,byte[] input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //提供用于加密和解密的加密密码的功能
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        //SecretKeySpec(密钥,算法)   从给定的字节数组构造一个密钥。
        SecretKey keySpec = new SecretKeySpec(key,"AES");
        //给定证书中的公钥初始化此密码。
        cipher.init(Cipher.ENCRYPT_MODE,keySpec);   //init(加密，密钥)
        return cipher.doFinal(input);       //在单部分操作中加密或解密数据，或完成多部分操作。
    }

    //解密
    private static byte[] decrypt(byte[] key,byte[] input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //提供用于加密和解密的加密密码的功能
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        //SecretKeySpec(密钥,算法)   从给定的字节数组构造一个密钥。
        SecretKey ketSpec = new SecretKeySpec(key,"AES");
        //给定证书中的公钥初始化此密码。
        cipher.init(Cipher.DECRYPT_MODE,ketSpec);       //init(解密,密钥)
        return cipher.doFinal(input);       //在单部分操作中加密或解密数据，或完成多部分操作。
    }

    public static void main(String[] args) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
        System.out.println("===========使用AES加密===============");
        /**
         * AES算法是目前应用最广泛的加密算法。我们先用ECB模式加密并解密：
         */
        //原文
        String message = "Hello,World";
        System.out.println("Message:"+message);

        //128为密钥 = 16 bytes Key
        byte[] key = "1234567890abcdef".getBytes(StandardCharsets.UTF_8);

        //加密
        byte[] data = message.getBytes(StandardCharsets.UTF_8);
        byte[] encrypted = encrypt(key,data);
        System.out.println("Encrypted："+ Base64.getEncoder().encodeToString(encrypted));

        //解密
        byte[] decrypted = decrypt(key,encrypted);
        System.out.println("Decrypted："+new String(decrypted,StandardCharsets.UTF_8));

        /**
         * Java标准库提供的对称加密接口非常简单，使用时按以下步骤编写代码：
         *      根据算法名称/工作模式/填充模式获取Cipher实例；
         *      根据算法名称初始化一个SecretKey实例，密钥必须是指定长度；
         *      使用SecretKey初始化Cipher实例，并设置加密或解密模式；
         *      传入明文或密文，获得密文或明文。
         */
    }
}
